const dayjs = require('dayjs');
import { projectStore, taskStore, documentStore, teamStore } from '../store_config';
import SmartCache from '../../helpers/smart_cache';

/**
 * 项目上下文助手类
 * 用于跨页面共享项目信息
 */
class ProjectContext {
  constructor() {
    this._currentProjectId = '';
    this._projectInfo = null;
    this._subscribers = [];
    
    // 观察者列表
    this._observers = [];
    
    // 项目关联的Store
    this._stores = {
      project: projectStore,
      task: taskStore,
      document: documentStore,
      team: teamStore
    };
    
    // TabBar页面数据中心
    this._tabBarDataCenter = {};
    
    // 创建上下文缓存
    this._contextCache = new SmartCache('projectContext', 30 * 60 * 1000); // 30分钟缓存
    
    // 初始化时尝试从缓存恢复上下文
    this._restoreFromCache();
    
    // 监听小程序隐藏和显示
    wx.onAppHide(() => this._saveToCache());
    wx.onAppShow(() => this._synchronizeContext());
  }
  
  /**
   * 设置当前项目ID
   * @param {String} projectId 项目ID
   * @param {Object} projectInfo 项目基本信息(可选)
   */
  setCurrentProjectId(projectId, projectInfo = null) {
    this._currentProjectId = projectId || '';
    
    if (projectInfo) {
      this._projectInfo = projectInfo;
    }
    
    // 同步到所有Store
    this._stores.task.setCurrentProjectId(this._currentProjectId);
    this._stores.document.setCurrentProjectId(this._currentProjectId);
    this._stores.team.setCurrentProjectId(this._currentProjectId);
    
    // 保存到缓存
    this._saveToCache();
    
    // 通知所有订阅者
    this._notifySubscribers();
    
    // 持久化到Storage
    if (this._currentProjectId) {
      wx.setStorageSync('currentProjectId', this._currentProjectId);
      
      if (this._projectInfo) {
        wx.setStorageSync('currentProjectInfo', this._projectInfo);
      }
    } else {
      wx.removeStorageSync('currentProjectId');
      wx.removeStorageSync('currentProjectInfo');
    }
  }
  
  /**
   * 获取当前项目ID
   * @returns {String} 项目ID
   */
  getCurrentProjectId() {
    // 如果没有缓存，尝试从Storage恢复
    if (!this._currentProjectId) {
      this._currentProjectId = wx.getStorageSync('currentProjectId') || '';
    }
    
    return this._currentProjectId;
  }
  
  /**
   * 获取当前项目信息
   * @returns {Object|null} 项目信息
   */
  getCurrentProjectInfo() {
    // 如果没有缓存，尝试从Storage恢复
    if (!this._projectInfo && this.getCurrentProjectId()) {
      this._projectInfo = wx.getStorageSync('currentProjectInfo') || null;
    }
    
    return this._projectInfo;
  }
  
  /**
   * 清除当前项目信息
   */
  clearCurrentProject() {
    this._currentProjectId = '';
    this._projectInfo = null;
    
    // 重置所有Store中的当前项目
    this._stores.project.resetCurrentProject();
    this._stores.task.resetCurrentTask();
    this._stores.document.resetCurrentDocument();
    this._stores.team.resetCurrentMember();
    
    // 清除缓存
    this._contextCache.remove('currentProject');
    
    // 清除Storage
    wx.removeStorageSync('currentProjectId');
    wx.removeStorageSync('currentProjectInfo');
    
    // 通知所有订阅者
    this._notifySubscribers();
  }
  
  /**
   * 订阅项目变化
   * @param {Function} callback 回调函数
   * @returns {Function} 取消订阅的函数
   */
  subscribe(callback) {
    if (typeof callback !== 'function') return () => {};
    
    this._subscribers.push(callback);
    
    // 返回取消订阅的函数
    return () => {
      const index = this._subscribers.indexOf(callback);
      if (index > -1) {
        this._subscribers.splice(index, 1);
      }
    };
  }
  
  /**
   * 通知所有订阅者
   */
  _notifySubscribers() {
    const projectId = this._currentProjectId;
    const projectInfo = this._projectInfo;
    
    this._subscribers.forEach(callback => {
      try {
        callback(projectId, projectInfo);
      } catch (e) {
        console.error('项目上下文通知订阅者失败:', e);
      }
    });
  }
  
  /**
   * 检查是否在项目上下文中
   * @returns {Boolean} 是否在项目上下文中
   */
  isInProjectContext() {
    return !!this._currentProjectId;
  }
  
  /**
   * 重新加载当前项目数据
   */
  async reloadCurrentProject() {
    if (!this._currentProjectId) return null;
    
    try {
      await this._stores.project.getProjectDetail(this._currentProjectId);
      
      // 更新当前项目信息
      this._projectInfo = this._stores.project.currentProject;
      
      // 保存到缓存
      this._saveToCache();
      
      return this._stores.project.currentProject;
    } catch (error) {
      console.error('重新加载项目数据失败', error);
      return null;
    }
  }
  
  /**
   * 加载项目相关的各种资源
   * @param {Boolean} includeTasks 是否加载任务
   * @param {Boolean} includeDocuments 是否加载文档
   * @param {Boolean} includeTeam 是否加载团队
   */
  async loadProjectResources({ includeTasks = true, includeDocuments = true, includeTeam = true }) {
    if (!this._currentProjectId) return;
    
    const promises = [];
    
    if (includeTasks) {
      promises.push(this._stores.task.getProjectTasks(this._currentProjectId));
    }
    
    if (includeDocuments) {
      promises.push(this._stores.document.getProjectDocuments(this._currentProjectId));
    }
    
    if (includeTeam) {
      promises.push(this._stores.team.getProjectTeam(this._currentProjectId));
    }
    
    try {
      await Promise.all(promises);
      
      // 通知所有观察者
      this._notifyObservers({
        type: 'resources_loaded',
        projectId: this._currentProjectId
      });
    } catch (error) {
      console.error('加载项目资源失败', error);
      throw error;
    }
  }
  
  /**
   * 添加项目上下文变更观察者
   * @param {Function} observer 观察者函数
   * @returns {Function} 用于移除此观察者的函数
   */
  addObserver(observer) {
    if (typeof observer !== 'function') {
      throw new Error('观察者必须是函数');
    }
    
    this._observers.push(observer);
    
    // 返回用于移除此观察者的函数
    return () => this.removeObserver(observer);
  }
  
  /**
   * 移除项目上下文变更观察者
   * @param {Function} observer 要移除的观察者函数
   */
  removeObserver(observer) {
    const index = this._observers.indexOf(observer);
    if (index !== -1) {
      this._observers.splice(index, 1);
    }
  }
  
  /**
   * 通知所有观察者
   * @param {Object} data 通知数据
   * @private
   */
  _notifyObservers(data) {
    this._observers.forEach(observer => {
      try {
        observer(data);
      } catch (error) {
        console.error('通知观察者时出错', error);
      }
    });
  }
  
  /**
   * 在页面中绑定项目上下文
   * @param {Object} page 页面实例
   * @param {String} projectId 项目ID
   * @param {Object} options 加载选项
   */
  bindToPage(page, projectId, options = {}) {
    const defaultOptions = {
      loadProject: true,
      loadTasks: false,
      loadDocuments: false,
      loadTeam: false,
      observeChanges: true
    };
    
    const settings = { ...defaultOptions, ...options };
    
    // 设置当前项目并加载项目详情
    this.setCurrentProjectId(projectId, settings.loadProject ? this._projectInfo : null)
      .then(() => {
        // 加载相关资源
        if (settings.loadTasks || settings.loadDocuments || settings.loadTeam) {
          return this.loadProjectResources({
            includeTasks: settings.loadTasks,
            includeDocuments: settings.loadDocuments,
            includeTeam: settings.loadTeam
          });
        }
      })
      .catch(error => {
        console.error('绑定项目上下文时出错', error);
      });
    
    // 观察上下文变更
    if (settings.observeChanges) {
      const observer = (data) => {
        // 确保页面已加载且存在setData方法
        if (page && typeof page.setData === 'function') {
          if (data.type === 'resources_loaded') {
            // 当项目资源加载完成时，更新页面数据
            page.setData({
              projectContext: {
                id: this._currentProjectId,
                project: this._projectInfo,
                tasks: settings.loadTasks ? this._stores.task.tasks : [],
                documents: settings.loadDocuments ? this._stores.document.documents : [],
                team: settings.loadTeam ? this._stores.team.members : []
              }
            });
          }
        }
      };
      
      // 添加观察者
      const removeObserver = this.addObserver(observer);
      
      // 在页面卸载时移除观察者
      const originalOnUnload = page.onUnload;
      page.onUnload = function() {
        removeObserver();
        if (typeof originalOnUnload === 'function') {
          originalOnUnload.call(this);
        }
      };
    }
  }
  
  /**
   * 保存上下文数据到缓存
   * @private
   */
  _saveToCache() {
    this._contextCache.set('currentProject', {
      id: this._currentProjectId,
      info: this._projectInfo
    });
  }
  
  /**
   * 从缓存恢复上下文数据
   * @private
   */
  _restoreFromCache() {
    try {
      // 提供正确的fetchFn回调函数
      this._contextCache.get('currentProject', async () => {
        // 如果缓存不存在，我们返回从Storage中读取的数据
        const id = wx.getStorageSync('currentProjectId') || '';
        const info = id ? wx.getStorageSync('currentProjectInfo') || null : null;
        
        return { id, info };
      }).then(cached => {
        if (cached && cached.id) {
          this._currentProjectId = cached.id;
          this._projectInfo = cached.info;
          
          // 同步到所有Store
          this._stores.task.setCurrentProjectId(this._currentProjectId);
          this._stores.document.setCurrentProjectId(this._currentProjectId);
          this._stores.team.setCurrentProjectId(this._currentProjectId);
          
          console.log('[ProjectContext] 已从缓存恢复项目上下文:', this._currentProjectId);
        }
      });
    } catch (err) {
      console.error('[ProjectContext] 从缓存恢复上下文失败:', err);
    }
  }
  
  /**
   * 同步上下文数据
   * 确保所有Store的状态与上下文一致
   * @private
   */
  _synchronizeContext() {
    if (!this._currentProjectId) return;
    
    // 重新加载当前项目数据
    this.reloadCurrentProject()
      .then(() => {
        // 通知上下文变更
        this._notifyObservers({
          type: 'context_synchronized',
          projectId: this._currentProjectId
        });
      })
      .catch(err => {
        console.error('[ProjectContext] 同步上下文失败:', err);
      });
  }
  
  /**
   * TabBar页面数据中心 - 存储数据
   * @param {String} key 数据键
   * @param {any} data 要存储的数据
   */
  setTabBarData(key, data) {
    this._tabBarDataCenter[key] = {
      data,
      timestamp: dayjs().valueOf()
    };
    
    // 通知数据变更
    this._notifyObservers({
      type: 'tabbar_data_changed',
      key,
      data
    });
  }
  
  /**
   * TabBar页面数据中心 - 获取数据
   * @param {String} key 数据键
   * @param {Number} maxAge 最大有效期（毫秒），默认不限制
   * @returns {any} 存储的数据，如果不存在或已过期则返回null
   */
  getTabBarData(key, maxAge = 0) {
    const item = this._tabBarDataCenter[key];
    
    if (!item) return null;
    
    // 检查是否已过期
    if (maxAge > 0) {
      const now = dayjs().valueOf();
      if (now - item.timestamp > maxAge) {
        // 数据已过期
        delete this._tabBarDataCenter[key];
        return null;
      }
    }
    
    return item.data;
  }
  
  /**
   * TabBar页面数据中心 - 清除数据
   * @param {String} key 要清除的数据键，不提供则清除所有数据
   */
  clearTabBarData(key) {
    if (key) {
      delete this._tabBarDataCenter[key];
    } else {
      this._tabBarDataCenter = {};
    }
    
    // 通知数据清除
    this._notifyObservers({
      type: 'tabbar_data_cleared',
      key
    });
  }
  
  /**
   * 检查数据一致性
   * 确保所有Store中的项目ID与上下文一致
   */
  verifyDataConsistency() {
    const issues = [];
    
    // 检查Task Store
    if (this._stores.task.currentProjectId !== this._currentProjectId) {
      issues.push('任务Store项目ID不一致');
      this._stores.task.setCurrentProjectId(this._currentProjectId);
    }
    
    // 检查Document Store
    if (this._stores.document.currentProjectId !== this._currentProjectId) {
      issues.push('文档Store项目ID不一致');
      this._stores.document.setCurrentProjectId(this._currentProjectId);
    }
    
    // 检查Team Store
    if (this._stores.team.currentProjectId !== this._currentProjectId) {
      issues.push('团队Store项目ID不一致');
      this._stores.team.setCurrentProjectId(this._currentProjectId);
    }
    
    return {
      isConsistent: issues.length === 0,
      issues
    };
  }
}

// 创建单例
export const projectContext = new ProjectContext(); 